/*
 * Copyright (c) 2025 HiSilicon (Shanghai) Technologies Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <string.h>
#include <stdio.h>

#include "oob_config.h"

#define SEED_COUNTS	512

int seed_table[SEED_COUNTS] = {
0x15fd5f9, 0x1ce1ce7, 0x1dcfdc2, 0x1d43d4e, 0x16d56d1, 0x098c98e, 0x1015010, 0x0e1ce1f,
0x047c47d, 0x12d92dc, 0x1e2de2b, 0x1b83b8f, 0x050650c, 0x16c96cd, 0x166f660, 0x158d589,
0x1fc7fca, 0x037c37c, 0x058a580, 0x0f32f3a, 0x005a051, 0x1da3dae, 0x11ab1a5, 0x17e97ed,
0x013c13c, 0x0e8ce8f, 0x08be8b7, 0x144344c, 0x0c2cc2f, 0x05cc5cd, 0x14bf4b0, 0x04e24e8,
0x1cd7cda, 0x182782b, 0x09d69df, 0x169d699, 0x1c9fc92, 0x12fd2f8, 0x170970d, 0x0284284,
0x15cb5c4, 0x148948d, 0x1e1be16, 0x0a26a2f, 0x0f16f1e, 0x1dbfdb2, 0x10d10d4, 0x022c22c,
0x0894896, 0x0f74f77, 0x12bb2b5, 0x053e534, 0x0694695, 0x1bfdbfa, 0x0a9ca9e, 0x0ac6acf,
0x12a72a9, 0x016616d, 0x17cd7c9, 0x1a3da3a, 0x086686f, 0x06ea6e0, 0x07d67dc, 0x00ee0e5,
0x07f27f8, 0x1d3dd3b, 0x1f59f5f, 0x0e9ee96, 0x1255250, 0x168f680, 0x17af7a0, 0x1ac1ac6,
0x0f7af72, 0x1cbbcb6, 0x126326d, 0x1881886, 0x0ea6eae, 0x1097099, 0x077e774, 0x18ed8ea,
0x09b49b6, 0x0bfabf3, 0x19c39cf, 0x0302309, 0x1b01b06, 0x0daada2, 0x1bcbbc7, 0x002a021,
0x1c39c3f, 0x0f66f6e, 0x05b25b8, 0x1c5bc56, 0x126d268, 0x1317319, 0x1635631, 0x0d92d9a,
0x1f11f17, 0x0b1ab13, 0x15f35fc, 0x10fb0f5, 0x121d218, 0x0fd2fda, 0x0aa4aa6, 0x1d19d1f,
0x192d92a, 0x141941d, 0x040c40d, 0x185985e, 0x003603d, 0x145f450, 0x143d439, 0x0da4da7,
0x0d3ad32, 0x05fa5f0, 0x0e12e1a, 0x13ad3a8, 0x1bc5bc2, 0x091291b, 0x1c83c8e, 0x000e005,
0x01a21a9, 0x1eafea2, 0x1715711, 0x112912c, 0x0cbccbf, 0x1f35f33, 0x02de2d5, 0x0d26d2e,
0x11b71b9, 0x153953d, 0x1e4fe42, 0x1661665, 0x116f161, 0x0f9af92, 0x147b474, 0x198b987,
0x1247249, 0x1eb3ebe, 0x04aa4a0, 0x15b55b1, 0x132f321, 0x0444445, 0x158358c, 0x1405401,
0x0c96c9e, 0x1b9fb93, 0x083c83e, 0x11db1d5, 0x099e997, 0x0afeaf7, 0x08ce8c7, 0x187387f,
0x11f11f4, 0x0eb4eb7, 0x194f943, 0x04b64bc, 0x0c6ac62, 0x1e23e2e, 0x1321324, 0x1467468,
0x1ccbcc6, 0x1e77e7a, 0x043a430, 0x091c91e, 0x1c55c53, 0x154954d, 0x1a33a3f, 0x125b255,
0x083283b, 0x0c76c7e, 0x06be6b4, 0x10b30bd, 0x1731735, 0x0c3ec36, 0x087a873, 0x00d60dd,
0x10a10a4, 0x0d8ed86, 0x075a750, 0x178b784, 0x0f86f8e, 0x1985982, 0x14dd4d9, 0x03c63cd,
0x0e2ae22, 0x0252259, 0x133d338, 0x03fe3f5, 0x1a51a56, 0x0a72a7b, 0x1157159, 0x00ba0b1,
0x0754755, 0x1f27f2a, 0x00a60ad, 0x1a05a02, 0x0eeeee6, 0x1915912, 0x10df0d1, 0x13e53e0,
0x080a803, 0x1b47b4b, 0x107907c, 0x1d21d27, 0x06d26d8, 0x172d729, 0x0ff6ffe, 0x1c13c1e,
0x1291294, 0x1941946, 0x1657658, 0x1d69d6f, 0x0334334, 0x06dc6dd, 0x02bc2bc, 0x01dc1dc,
0x1bb5bb2, 0x04d44d5, 0x1367369, 0x0b4eb47, 0x1daddab, 0x084c84e, 0x06ac6ad, 0x18a58a2,
0x123923c, 0x174f740, 0x18ab8a7, 0x1077079, 0x0a92a9b, 0x097e977, 0x1c1dc1b, 0x1031034,
0x1fabfa6, 0x09c49c6, 0x0e62e6a, 0x169369c, 0x0142149, 0x0ed6ede, 0x01f61fd, 0x063c63d,
0x1421425, 0x1b55b52, 0x130b305, 0x1ecdecb, 0x011611d, 0x1161164, 0x067a670, 0x18b98be,
0x14a34ac, 0x0be6bef, 0x0c64c67, 0x19e99ee, 0x10af0a1, 0x135f351, 0x0564565, 0x159f590,
0x004604d, 0x140b404, 0x173f730, 0x1bd7bdb, 0x10f50f0, 0x1111114, 0x0d56d5e, 0x122b225,
0x0a34a36, 0x07ca7c0, 0x12e12e4, 0x11a51a0, 0x18c78cb, 0x02e62ed, 0x186f863, 0x1a43a4f,
0x14c14c5, 0x0b5cb5e, 0x05f45f5, 0x03d43d4, 0x104f041, 0x0522528, 0x128328d, 0x1681685,
0x1b7fb73, 0x1cfdcfb, 0x1d87d8a, 0x1225220, 0x0c84c87, 0x176b764, 0x0bdebd7, 0x0c8ac82,
0x1fc9fcf, 0x1b5bb57, 0x109909c, 0x1e97e9a, 0x114b145, 0x0584585, 0x0f0af02, 0x088688f,
0x13c13c4, 0x183b837, 0x0344344, 0x0062069, 0x144d449, 0x1e15e13, 0x0e6ce6f, 0x1475471,
0x0e54e57, 0x129f291, 0x1ba7bab, 0x1707708, 0x084284b, 0x1c37c3a, 0x16ab6a4, 0x01e41e4,
0x078c78d, 0x052c52d, 0x1d9bd96, 0x15a75a8, 0x02c22c9, 0x1fb9fbf, 0x117317d, 0x0954956,
0x0674675, 0x19bd9ba, 0x119d198, 0x18c98ce, 0x0d44d47, 0x161f610, 0x1d4dd4b, 0x0c06c0e,
0x16c76c8, 0x1d51d57, 0x0b14b16, 0x185785b, 0x13f73f9, 0x1a75a72, 0x054e544, 0x15ef5e0,
0x074674c, 0x01ea1e1, 0x16ff6f0, 0x0222229, 0x01ac1ac, 0x146946d, 0x0e7ee76, 0x034a341,
0x076c76d, 0x1741745, 0x1417418, 0x098298b, 0x16b96bd, 0x093693f, 0x1addada, 0x1c91c97,
0x020620d, 0x0e24e27, 0x110d108, 0x0decdef, 0x03b63bd, 0x044a440, 0x190990e, 0x0874876,
0x1351354, 0x16b76b8, 0x1a5fa53, 0x0132139, 0x1ab1ab6, 0x1a67a6b, 0x08e48e6, 0x0782788,
0x04c64cc, 0x1fedfeb, 0x072a720, 0x089a893, 0x0b76b7f, 0x1c2bc26, 0x0c14c17, 0x049c49d,
0x1cd9cdf, 0x08ea8e3, 0x1ca9caf, 0x1c47c4a, 0x0d9cd9f, 0x18f18f6, 0x092a923, 0x1f61f67,
0x0d0cd0f, 0x14f74f8, 0x061661c, 0x0aecaee, 0x1b1db1a, 0x12a92ac, 0x193f933, 0x137b375,
0x15c55c1, 0x119319d, 0x015e155, 0x1a89a8e, 0x177977d, 0x1a9ba97, 0x1f4bf46, 0x1aa3aaf,
0x162962d, 0x1591595, 0x14eb4e4, 0x1ee7eea, 0x13bf3b1, 0x1edfed2, 0x0f94f97, 0x1b8db8a,
0x1501505, 0x064c64d, 0x14f94fd, 0x12d72d9, 0x0e82e8a, 0x08ac8ae, 0x0d1ed16, 0x0d72d7a,
0x17d17d5, 0x15bb5b4, 0x192392f, 0x1f45f43, 0x021a211, 0x1bd9bde, 0x16e36ec, 0x15e15e5,
0x121321d, 0x13dd3d8, 0x10e90ec, 0x06a26a8, 0x156356c, 0x0bccbce, 0x157f570, 0x1611615,
0x11c91cc, 0x1811816, 0x1c25c23, 0x1d95d93, 0x04fe4f4, 0x0ecaec2, 0x1fdbfd6, 0x182982e,
0x094694f, 0x19b39bf, 0x195395f, 0x1b39b3e, 0x11e31ed, 0x1ebdebb, 0x1a19a1e, 0x1e31e37,
0x073673c, 0x0a8ea87, 0x1d67d6a, 0x0552558, 0x19d19d6, 0x10cd0c8, 0x1547548, 0x14e54e1,
0x151351c, 0x0ef2efa, 0x02cc2cc, 0x151d519, 0x0c52c5a, 0x0b22b2b, 0x1f9df9b, 0x09fc9fe,
0x0a6ea67, 0x1dddddb, 0x0e0ee06, 0x1f29f2f, 0x171b714, 0x0b3eb37, 0x0a02a0b, 0x18b78bb,
0x09f29fb, 0x1db1db7, 0x1aadaaa, 0x115915c, 0x108b085, 0x0fa2faa, 0x1ea1ea7, 0x090e907,
0x197797b, 0x1e8be86, 0x0194194, 0x18db8d7, 0x17b37bc, 0x0bc2bcb, 0x1dc1dc7, 0x055c55d,
0x0b64b66, 0x07c47c5, 0x0264264, 0x0cdecd6, 0x1f57f5a, 0x12c52c0, 0x179979d, 0x102d028,
0x06f66fc, 0x18d58d2, 0x0bf4bf6, 0x09ee9e7, 0x0392399, 0x102302d, 0x184b847, 0x188f883,
0x1b2bb27, 0x1a21a26, 0x190790b, 0x042642c, 0x105305d, 0x07a67ac, 0x1a4da4a, 0x0214214
};


/* Polynomial X25+X22+1=0 */
int lfsr25(int seed)
{
	return (((seed >> 14) ^ (seed >> 17)) & 0xFF) | ((seed & 0x1FFFF) << 8);
}

void page_random_gen(unsigned char *pagebuf, enum page_type pagetype, enum ecc_type ecctype, int pageindex, int oobused)
{
 	struct oob_info *info;
	unsigned int i, pagesize, seed, oobsize;
	unsigned int seed_reset = 0;
	int rnc8;

	info = get_oob_info(pagetype, ecctype);
	if (info == NULL)
		return;

	if (oobused)
		oobsize = oobused;
	else
		oobsize = info->oobsize;

	pagesize = get_pagesize(pagetype);

	seed = seed_table[pageindex];

	for (i = 0; i < pagesize + oobsize; i++) {
		/* for nandcv610/nandcv620/fmc100 only, empty page flag do not need randomizer.!!! */
		if ((i == pagesize + oobsize - 2) || (i == pagesize + oobsize - 1))
			continue;

		if ((pagesize == _16K) && (i >= (pagesize + oobsize) / 2)) { /* 2: next half of chip nand real page zise */
			if (!seed_reset) {
				seed = seed_table[pageindex];
				seed_reset = 1;
			}
			rnc8 = (((seed & 3) << 6) | ((seed >> 2) & 0x3f)) & 0xff;
		} else {
			rnc8 = seed & 0xFF;
		}

		/* for nandcv610/nandcv620 only, BB do not need randomizer.!!! */
		if ((i != pagesize) && (i != (pagesize + 1)))
			pagebuf[i] = pagebuf[i] ^ (rnc8);

		seed = lfsr25(seed);
	}
}
